/**
 * 
 */
package com.android.dwt.fragment;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.res.Resources;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ExpandableListView.OnGroupCollapseListener;
import android.widget.ExpandableListView.OnGroupExpandListener;
import android.widget.SimpleExpandableListAdapter;
import android.widget.TextView;

import com.android.dwt.Position;
import com.android.dwt.R;
import com.android.dwt.TaskItem;
import com.android.dwt.data.DBTaskAdapter;
import com.android.dwt.data.GTDApp;
import com.android.dwt.ui.MainAct;
import com.android.dwt.ui.TaskDetailAct;
import com.android.dwt.util.C;
import com.android.dwt.util.TaskUtil;

/**
 * @author xiang
 *
 */
public class LocationFrag extends Fragment
		implements OnClickListener, OnChildClickListener, OnGroupExpandListener, OnGroupCollapseListener {
	
	private final String TAG = "LocationFrag";
	private final String[] fromCols = new String[] {
			"item_name",
			"item_context",
			"item_pos",
			"item_tags"};
	private final int[] toLayouts = new int[] {
			R.id.tv_task,
			R.id.tv_row_context,
			R.id.tv_row_pos,
			R.id.tv_row_tag};
	
	private GTDApp mGa;
	private ExpandableListView mElvPosition;
	private MyListAdapter mAdapter;
	private ArrayList<Boolean> mExpandGroup;
	private boolean mIsCollapse;
	private boolean mIsTitleClick;
	private int mListIndex;
	
	private MainAct mMain;
	private Resources mRsrc;
	private SimpleDateFormat mSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
	
	private ArrayList<HashMap<String, Object>> mGroups = new ArrayList<HashMap<String, Object>>();
	private ArrayList<ArrayList<HashMap<String, Object>>> mChildren =
			new ArrayList<ArrayList<HashMap<String, Object>>>();
	
//	private Button mAddPos;
//	private Button mMgrPos;
	
	
	/*
	 * Define custom SimpleExpandableListViewAdapter
	 */
	private class MyListAdapter extends SimpleExpandableListAdapter {
		
		private LayoutInflater mInflater;
		
		
		private class ViewHolder {
			
			TextView prior;
			CheckBox cb;
			TextView title;
			TextView list;
			TextView context;
			TextView position;
//			TextView project;
			TextView tags;

			TextView flag;
		}
		
		
		public MyListAdapter(Context context,
				List<? extends Map<String, ?>> groupData, int groupLayout,
				String[] groupFrom, int[] groupTo,
				List<? extends List<? extends Map<String, ?>>> childData,
				int childLayout, String[] childFrom, int[] childTo) {
			
			super(context, groupData, groupLayout, groupFrom, groupTo, childData,
					childLayout, childFrom, childTo);
			// TODO Auto-generated constructor stub

			mInflater = LayoutInflater.from(context);
		}
		
		@Override
		public View getChildView(final int groupPosition, final int childPosition,
				boolean isLastChild, View convertView, ViewGroup parent) {
			
//			return super.getChildView(groupPosition, childPosition, isLastChild,
//					convertView, parent);
			
			final ViewHolder holder;

			if (convertView == null) {
				
				convertView = mInflater.inflate(R.layout.row_task, null);

				holder = new ViewHolder();
				
				Log.e(TAG, "convertView is empty: group:"+groupPosition+" children:"+childPosition);

				// get views
				holder.prior = (TextView) convertView.findViewById(R.id.tv_row_prior);
				holder.cb = (CheckBox) convertView.findViewById(R.id.cb_completed);
				holder.title = (TextView) convertView.findViewById(R.id.tv_task);
				holder.list = (TextView) convertView.findViewById(R.id.tv_list);
				holder.context = (TextView) convertView.findViewById(R.id.tv_row_context);
				holder.position = (TextView) convertView.findViewById(R.id.tv_row_pos);
				// holder.project = (TextView).convertView.findViewById(R.id.tv_row_prj);
				holder.tags = (TextView) convertView.findViewById(R.id.tv_row_tag);
				holder.flag = (TextView) convertView.findViewById(R.id.tv_row_flag);

				convertView.setTag(holder);

			} else {
				
				holder = (ViewHolder) convertView.getTag();
				
				Log.e(TAG, "convertView not empty: group:"+groupPosition+" children:"+childPosition);

			}
			

			// fill data
			HashMap<String, Object> hm = mChildren.get(groupPosition).get(childPosition);
			
			// Priority
			String prior = (String) hm.get("item_prior");
			if (prior.equals("无")) {
				
				holder.prior.setBackgroundColor(mRsrc.getColor(R.color.none_prior));
				
			} else if (prior.equals("高")) {
				
				holder.prior.setBackgroundColor(mRsrc.getColor(R.color.high_prior));
				
			} else if (prior.equals("中")) {
				
				holder.prior.setBackgroundColor(mRsrc.getColor(R.color.medium_prior));
				
			} else if (prior.equals("低")) {
				
				holder.prior.setBackgroundColor(mRsrc.getColor(R.color.low_prior));
			}

			if (holder.cb.isChecked())
				Log.e(TAG, "children["+groupPosition+"]["+childPosition+"] is checked");
			else
				Log.e(TAG, "children["+groupPosition+"]["+childPosition+"] is unchecked");
			
			holder.cb.setOnCheckedChangeListener(null);
			holder.cb.setChecked(false);		// fix this bug
			holder.cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
				
				@Override
				public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
					
					Log.e(TAG, "checkbox " + childPosition + " checked!");
					
					HashMap<String, Object> hm = mChildren.get(groupPosition).get(childPosition);
					long rowId = (Long) hm.get("item_id");
					TaskItem ti = mGa.getDbta().getTaskItem(rowId);
					
					mListIndex = TaskUtil.getListIndex(mGa.mList, ti.getListName());

					if (isChecked) {		// task is completed
						
						holder.flag.setVisibility(View.VISIBLE);

						ti.setCompletedStatus(C.TASK.COMPLETED);
						mGa.getDbta().updateTask(rowId, ti);
						
						SharedPreferences prefs = mMain.getSharedPreferences(GTDApp.strList, GTDApp.MODE);
						Editor editor = prefs.edit();
						
						if (mListIndex != -1) {		// in some list
							
							// update the counter
							int count = (Integer) mGa.lists.get(mListIndex).get("item_count");
							mGa.lists.get(mListIndex).put("item_count", count-1);
							
							editor.putInt("List_count["+mListIndex+"]", count-1);
							
						} else {
							
							String list = ti.getListName();
							int index = TaskUtil.getListIndex(mGa.mList, list);
							
							int count = (Integer) mGa.lists.get(index).get("item_count");
							mGa.lists.get(index).put("item_count", count-1);
							
							editor.putInt("List_count["+index+"]", count-1);
						}
						
						editor.commit();
						
					} else {
						
						holder.flag.setVisibility(View.INVISIBLE);

						ti.setCompletedStatus(C.TASK.UNCOMPLETED);
						mGa.getDbta().updateTask(rowId, ti);
						
						SharedPreferences prefs = mMain.getSharedPreferences(GTDApp.strList, GTDApp.MODE);
						Editor editor = prefs.edit();
						
						if (mListIndex != -1) {
							
							// update the counter
							int count = (Integer) mGa.lists.get(mListIndex).get("item_count");
							mGa.lists.get(mListIndex).put("item_count", count+1);
							
							editor.putInt("List_count[" + mListIndex + "]", count+1);
							
						} else {
							
							// get original list index
							String list = ti.getListName();
							int index = TaskUtil.getListIndex(mGa.mList, list);
							
							Log.e(TAG, "original list and its index are: " + list + " " + index);
							
							int count = (Integer) mGa.lists.get(index).get("item_count");
							mGa.lists.get(index).put("item_count", count+1);
							
							editor.putInt("List_count["+index+"]", count+1);
						}
						
						editor.commit();
					}
					
					buttonView.setTag(null);
				}
			});
			
			holder.title.setText((String) hm.get("item_name"));
			
			holder.list.setText("+"
					+ (String) mChildren.get(groupPosition).get(childPosition).get("item_list"));

			String ctt = (String) hm.get("item_context");
			if (ctt.equals(mGa.getContexts().get(0))) // no context
				holder.context.setText("");
			else
				holder.context.setText("@" + ctt);

			String pos = (String) hm.get("item_pos");
			if (pos.equals(mGa.getPositions().get(0).getPlace()))
				holder.position.setText("");
			else
				holder.position.setText("&" + pos);

			
			/*String prj = (String) hm.get("item_project");
			if (prj.equals(mGa.getProjects().get(0)))
				holder.project.setText("");
			else
				holder.project.setText("#" + prj);*/
			 
			if (((String) hm.get("item_list")).equals(mGa.mList[GTDApp.AGENDA])) {		// agenda
				
				SimpleDateFormat sdf = new SimpleDateFormat("MM-dd");
				
				try {
					
					Date time = mSdf.parse((String) hm.get("item_st"));
					holder.tags.setText(sdf.format(time));
					
				} catch (ParseException e) {
					
					e.printStackTrace();
				}
				
			} else {
				
				holder.tags.setText((String) hm.get("item_tags"));
			}

			holder.flag.setVisibility(View.INVISIBLE);		// setting to default (fix this bug)
			
			return convertView;
		}
		
		@Override
		public View newGroupView(boolean isExpanded, ViewGroup parent) {
			// TODO Auto-generated method stub
//			return super.newGroupView(isExpanded, parent);
			
			return mInflater.inflate(R.layout.grp_pos, parent, false);
		}
		
		@Override
		public View getGroupView(int groupPosition, boolean isExpanded,
				View convertView, ViewGroup parent) {
			
//			return super.getGroupView(groupPosition, isExpanded, convertView, parent);
			
			View v = newGroupView(isExpanded, parent);
			
			TextView groupName = (TextView) v.findViewById(R.id.tv_pos_group);
			groupName.setText((String) mGroups.get(groupPosition).get("group_name"));
			
			TextView childCount = (TextView) v.findViewById(R.id.tv_pos_count);
			int count = (Integer) mGroups.get(groupPosition).get("child_count");
			if (count == 0) {
				
				childCount.setVisibility(View.INVISIBLE);
				
			} else {
				
				childCount.setVisibility(View.VISIBLE);
				childCount.setText(String.valueOf(count));
			}
			
			return v;
		}
		
	}		// end class MyListAdapter
	
	
	public static LocationFrag newInstance() {
		
		LocationFrag frag = new LocationFrag();
		
		return frag;
	}
	
	@Override
	public void onAttach(Activity activity) {
		
		super.onAttach(activity);
		
		mMain = (MainAct) activity;
	}
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		
//		setContentView(R.layout.panel_pos);
		
//		initViews();
		
		mGa = (GTDApp) mMain.getApplication();
		mRsrc = getResources();
	}
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		
//		return super.onCreateView(inflater, container, savedInstanceState);
		
		View view = inflater.inflate(R.layout.panel_pos, container, false);
		
		return view;
	}
	
	@Override
	public void onViewCreated(View view, Bundle savedInstanceState) {
		
		Log.e(TAG, "onViewCreated is called!");
		
		super.onViewCreated(view, savedInstanceState);
		
		initViews(view);
	}
	
	
	private void initViews(View view) {
		/*mAddPos = (Button) getParent().findViewById(R.id.btn_add_pos);
		mAddPos.setOnClickListener(this);*/
		
		getAdapterData();
		
		
		mElvPosition = (ExpandableListView) view.findViewById(R.id.elv_pos);
		mElvPosition.setOnChildClickListener(this);
		
		/*TextView tvContext = (TextView) getParent().findViewById(R.id.tv_pos_title);
		tvContext.setOnClickListener(this);*/
		
		// default is collapsing all groups
		mExpandGroup = new ArrayList<Boolean>();
		for (int i=0; i<mGroups.size(); i++)
			mExpandGroup.add(true);
		
		mAdapter = new MyListAdapter(
				mMain,
				mGroups,
				R.layout.grp_pos,
				new String[] { "group_name", "child_count" },
				new int[] { R.id.tv_pos_group, R.id.tv_pos_count },
				mChildren,
				R.layout.row_task,
				fromCols,
				toLayouts);
		mElvPosition.setAdapter(mAdapter);
		mAdapter.notifyDataSetChanged();
		
//		expandGroups();
		
//		mMgrPos = (Button) getParent().findViewById(R.id.btn_mgr_pos);
//		mMgrPos.setOnClickListener(this);
	}
	
	@Override
	public void onStart() {
		// TODO Auto-generated method stub
		super.onStart();
	}
	
	@Override
	public void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		
		Log.e(TAG, "onResume is called!");
		
		updateAdapterView();
	}
	
	private void updateAdapterView() {
		
		refreshAdapterData();
		mAdapter.notifyDataSetChanged();
	}
	
	private void refreshAdapterData() {
		
		getAdapterData();
	}
	
	private void collapseGroups() {
		
		for (int i=0; i<mGroups.size(); i++) {
			
			mElvPosition.collapseGroup(i);
		}
		
	}
	
	private void expandGroups() {
		
		for (int i=0; i<mGroups.size(); i++) {
			
			mElvPosition.expandGroup(i);
		}
		
	}
	
	private void getAdapterData() {
		
		ArrayList<HashMap<String,Object>> items = null;
		HashMap<String, Object> hm;
		Cursor cursor = null;
		
		// clear previous data
		mGroups.clear();
		for (int i=0; i<mChildren.size(); i++) {
			mChildren.get(i).clear();
		}
		mChildren.clear();
		
		// get all positions
		ArrayList<String> al = new ArrayList<String>();
		ArrayList<Position> pos = mGa.getPositions();
		for (int i=0; i<pos.size(); i++) {
			al.add(pos.get(i).getPlace());
		}
		
		// reorder the positions
		/*int size = al.size();
		int[] index = new int[size];
		for (int i=0; i<size-1; i++)
			index[i] = i+1;
		index[size-1] = 0;*/
		
		// default is collapsing all groups
		mExpandGroup = new ArrayList<Boolean>();
		for (int i=0; i<al.size(); i++)
			mExpandGroup.add(true);
		
		for (int i=0; i<al.size(); i++) {
			
			String sql = "select * from " + mGa.getDbta().getTableName()
					+ " where " + DBTaskAdapter.KEY_POS + "=\"" + al.get(i)
					+ "\" AND " + DBTaskAdapter.KEY_COMPLETED + "=" + C.TASK.UNCOMPLETED
					+ " order by task_created desc";
			cursor = mGa.getDbta().excuteSQL(sql);
			
			if (cursor == null) {
				
				continue;
			}
			
			Log.e(TAG, "number of context " + al.get(i) + ": " + cursor.getCount());
			
			items = new ArrayList<HashMap<String, Object>>();
			fillArray(cursor, items);
			mChildren.add(items);
			
			hm = new HashMap<String, Object>();
			hm.put("group_name", al.get(i));
			hm.put("child_count", items.size());
			mGroups.add(hm);
			
			cursor.close();
		}
		
	}
	
	private void fillArray(Cursor taskCursor, ArrayList<HashMap<String, Object>> items) {
		
		HashMap<String, Object> hm;
		
		if (taskCursor.moveToFirst()) {
			
			do {
				
				long rowId = taskCursor.getLong(DBTaskAdapter.COL_ID);
				String task = taskCursor.getString(DBTaskAdapter.COL_TASK_NAME);
				String note = taskCursor.getString(DBTaskAdapter.COL_TASK_NOTE);
				String list = taskCursor.getString(DBTaskAdapter.COL_TASK_LIST);
				
				String ctt = taskCursor.getString(DBTaskAdapter.COL_TASK_CONTEXT);
				String prj = taskCursor.getString(DBTaskAdapter.COL_TASK_PROJECT);
				String pos = taskCursor.getString(DBTaskAdapter.COL_TASK_POS);
				
				int status = taskCursor.getInt(DBTaskAdapter.COL_TASK_STATUS);
				String st = taskCursor.getString(DBTaskAdapter.COL_TASK_ST);
				String et = taskCursor.getString(DBTaskAdapter.COL_TASK_ET);
				String repeat = taskCursor.getString(DBTaskAdapter.COL_TASK_REPEAT);
				String remind = taskCursor.getString(DBTaskAdapter.COL_TASK_REMIND);
				
				if (list.equals(mGa.mList[GTDApp.AGENDA]) && repeat.length()>0) {
					
					Date sTime = null;
					Calendar today = Calendar.getInstance();
					Calendar cldStart = Calendar.getInstance();
					SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
					
					Log.e(TAG, "today: "+sdf.format(today.getTime()));
					Log.e(TAG, "this task: "+st);
					
					try {
						
						sTime = sdf.parse(st);
						cldStart.setTime(sTime);
						
					} catch (ParseException e) {
						
						e.printStackTrace();
					}
					
					today.clear(Calendar.MILLISECOND);
					cldStart.clear(Calendar.MILLISECOND);
					
					today.set(Calendar.SECOND, 0);
					cldStart.set(Calendar.SECOND, 0);
					
					today.add(Calendar.DAY_OF_MONTH, 1);	// tomorrow
					if (cldStart.after(today)) {		// only display today and tomorrow repeat task
						
						continue;
					}
					
				}
				
				String prior = taskCursor.getString(DBTaskAdapter.COL_TASK_PRIOR);
				String tags = taskCursor.getString(DBTaskAdapter.COL_TASK_TAG);
				String created = taskCursor.getString(DBTaskAdapter.COL_TASK_CREATED);
				int completed = taskCursor.getInt(DBTaskAdapter.COL_TASK_COMPLETED);
				
				
				hm = new HashMap<String, Object>();
				hm.put("item_id", rowId);
				hm.put("item_name", task);
				hm.put("item_note", note);
				hm.put("item_list", list);
				
				hm.put("item_context", ctt);
				hm.put("item_project", prj);
				hm.put("item_pos", pos);
				
				hm.put("item_status", status);
				hm.put("item_st", st);
				hm.put("item_et", et);
				hm.put("item_repeat", repeat);
				hm.put("item_remind", remind);
				
				hm.put("item_prior", prior);
				hm.put("item_tags", tags);
				hm.put("item_created", created);
				hm.put("item_completed", completed);
				
				items.add(hm);
			} while (taskCursor.moveToNext());
		}
	}
	
	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		Intent itt = null;
		
		switch (v.getId()) {
		
    		/*case R.id.btn_mgr_pos:
    			itt = new Intent(LocationAct.this, MgrPositionAct.class);
    			
    			startActivity(itt);
    			break;*/
    			
    		/*case R.id.btn_add_pos:
    			itt = new Intent(LocationAct.this, AddPositionAct.class);
    			
    			startActivity(itt);
    			break;*/
    			
    		case R.id.tv_pos_title:
    			setTitleEvent();
    			
    			break;
    			
    		default:
    			break;
		}
		
	}
	
	private void setTitleEvent() {
		
		for (int i=0; i<mGroups.size(); i++)
			Log.e(TAG, "mGroups["+i+"]: "+mExpandGroup.get(i)+"\n");
		
		mIsTitleClick = true;
		
		if (mIsCollapse) {		// expand groups to their previous state
			mIsCollapse = false;
			
			for (int i=0; i<mGroups.size(); i++) {
				if (mExpandGroup.get(i).booleanValue())
					mElvPosition.expandGroup(i);
				else
					mElvPosition.collapseGroup(i);
			}
		} else {	// collapse groups
			mIsCollapse = true;
			
			for (int i=0; i<mGroups.size(); i++)
				mElvPosition.collapseGroup(i);
		}
		
		mIsTitleClick = false;
	}
	
	/*private TaskItem hashMap2Task(HashMap<String, Object> hm) {
		
		TaskItem task;
		
		String name = (String) hm.get("item_name");
		String note = (String) hm.get("item_note");
		String list = (String) hm.get("item_list");
		task = new TaskItem(name, note, list);
		
		task.setContext((String) hm.get("item_context"));
		task.setProject((String) hm.get("item_project"));
		task.setPosition((String) hm.get("item_pos"));
		
		if (((Integer) hm.get("item_status")) == 1)
			task.setAllDay(true);
		else
			task.setAllDay(false);
		
		task.setStartTime((String) hm.get("item_st"));
		task.setEndTime((String) hm.get("item_et"));
		task.setRepeat((String) hm.get("item_repeat"));
		task.setRemind((String) hm.get("item_remind"));
		task.setPrior((String) hm.get("item_prior"));
		task.setTags((String) hm.get("item_tags"));
		task.setCreated((String) hm.get("item_created"));
		task.setCompletedStatus((Integer) hm.get("item_completed"));
		
		return task;
	}*/

	@Override
	public boolean onChildClick(ExpandableListView parent, View v,
			int groupPosition, int childPosition, long id) {
		
		Log.e(TAG, "child["+groupPosition+"]["+childPosition+"]"+" is clicked!");
		
		HashMap<String, Object> hmSelected = (HashMap<String, Object>) mChildren
				.get(groupPosition).get(childPosition);
//		TaskItem task = hashMap2Task(hmSelected);
		
		long posInTable = (Long) hmSelected.get("item_id");
		
		String list = (String) hmSelected.get("item_list");
		mListIndex = TaskUtil.getListIndex(mGa.mList, list);
		
//		Log.e(tag, "listIndex is: "+listIndex);
		
		Intent itt = new Intent(mMain, TaskDetailAct.class);
		
		itt.putExtra("row_id", posInTable);
//		itt.putExtra("task", task);
		itt.putExtra("list_index", mListIndex);
		
		startActivity(itt);
		
		return false;
	}


	@Override
	public void onGroupCollapse(int groupPosition) {
		
		if (!mIsTitleClick) {
			
			mExpandGroup.set(groupPosition, true);
			mIsCollapse = false;
		}
		
	}


	@Override
	public void onGroupExpand(int groupPosition) {
		
		if (!mIsTitleClick) {
			
			mExpandGroup.set(groupPosition, false);
			mIsCollapse = false;
		}
		
	}
	
}
